﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.LIB;
using YJKArchUtils.Utils;
using YRevitJig;

namespace YJKRevitWallModule.WallModule.CreateWall
{
	public class YRevitJigExtend : XUiJigBase, IDisposable
	{
		public void SetJigInfo(UseData tmpData)
		{
			double num = 0.0;
			double num2 = 0.0;
			double num3 = 0.0;
			double num4 = 0.0;
			if (tmpData.wallTypeId == ElementId.InvalidElementId)
			{
				this.nowWidth = Common.MMToFeet(double.Parse(tmpData.strLeftKeepWarmWidth) + double.Parse(tmpData.strWallWidth) + double.Parse(tmpData.strRightKeepWarmWidth));
			}
			else
			{
				try
				{
					WallType wallType = this.m_uiDoc.Document.GetElement(tmpData.wallTypeId) as WallType;
					this.GetLayerThickness(wallType, ref num, ref num2, ref num3, ref num4);
					this.nowWidth = wallType.Width;
				}
				catch (Exception)
				{
				}
			}
			this.MutilLineDist.Clear();
			if (tmpData.location != LocationCv.CoreCenter)
			{
				if (tmpData.location == LocationCv.CoreLayerInner)
				{
					if (tmpData.wallTypeId == ElementId.InvalidElementId && tmpData.strRightKeepWarmWidth == "0")
					{
						this.PointAlignType = YRevitJigExtend.AlignType.eRight;
						if (this.nowWidth > 0.0)
						{
							this.MutilLineDist.Add(this.nowWidth / 2.0);
							this.MutilLineDist.Add(this.nowWidth / 2.0);
							return;
						}
					}
					else
					{
						if (tmpData.wallTypeId == ElementId.InvalidElementId && tmpData.strRightKeepWarmWidth != "0")
						{
							this.PointAlignType = YRevitJigExtend.AlignType.eMiddle;
							double num5 = Common.MMToFeet(double.Parse(tmpData.strRightKeepWarmWidth));
							this.MutilLineDist.Add(this.nowWidth - num5);
							this.MutilLineDist.Add(num5);
							return;
						}
						if (tmpData.wallTypeId != ElementId.InvalidElementId)
						{
							this.PointAlignType = YRevitJigExtend.AlignType.eMiddle;
							this.MutilLineDist.Add(num2);
							this.MutilLineDist.Add(this.nowWidth - num2);
							return;
						}
					}
				}
				else if (tmpData.location == LocationCv.CoreLayerOuter)
				{
					if (tmpData.wallTypeId == ElementId.InvalidElementId && tmpData.strLeftKeepWarmWidth == "0")
					{
						this.PointAlignType = YRevitJigExtend.AlignType.eLeft;
						if (this.nowWidth > 0.0)
						{
							this.MutilLineDist.Add(this.nowWidth / 2.0);
							this.MutilLineDist.Add(this.nowWidth / 2.0);
							return;
						}
					}
					else
					{
						if (tmpData.wallTypeId == ElementId.InvalidElementId && tmpData.strLeftKeepWarmWidth != "0")
						{
							this.PointAlignType = YRevitJigExtend.AlignType.eMiddle;
							double num6 = Common.MMToFeet(double.Parse(tmpData.strLeftKeepWarmWidth));
							this.MutilLineDist.Add(num6);
							this.MutilLineDist.Add(this.nowWidth - num6);
							return;
						}
						if (tmpData.wallTypeId != ElementId.InvalidElementId)
						{
							this.PointAlignType = YRevitJigExtend.AlignType.eMiddle;
							this.MutilLineDist.Add(num);
							this.MutilLineDist.Add(this.nowWidth - num);
							return;
						}
					}
				}
				else if (tmpData.location == LocationCv.SurfaceLayerInner)
				{
					if (!(tmpData.wallTypeId != ElementId.InvalidElementId))
					{
						this.PointAlignType = YRevitJigExtend.AlignType.eMiddle;
						this.MutilLineDist.Add(this.nowWidth - num4);
						this.MutilLineDist.Add(num4);
						return;
					}
					this.PointAlignType = YRevitJigExtend.AlignType.eRight;
					if (this.nowWidth > 0.0)
					{
						this.MutilLineDist.Add(this.nowWidth / 2.0);
						this.MutilLineDist.Add(this.nowWidth / 2.0);
						return;
					}
				}
				else if (tmpData.location == LocationCv.SurfaceLayerOuter)
				{
					if (!(tmpData.wallTypeId != ElementId.InvalidElementId))
					{
						this.PointAlignType = YRevitJigExtend.AlignType.eMiddle;
						this.MutilLineDist.Add(num3);
						this.MutilLineDist.Add(this.nowWidth - num3);
						return;
					}
					this.PointAlignType = YRevitJigExtend.AlignType.eLeft;
					if (this.nowWidth > 0.0)
					{
						this.MutilLineDist.Add(this.nowWidth / 2.0);
						this.MutilLineDist.Add(this.nowWidth / 2.0);
						return;
					}
				}
				else if (tmpData.location == LocationCv.WallCenter)
				{
					this.PointAlignType = YRevitJigExtend.AlignType.eMiddle;
					if (this.nowWidth > 0.0)
					{
						this.MutilLineDist.Add(this.nowWidth / 2.0);
						this.MutilLineDist.Add(this.nowWidth / 2.0);
					}
				}
				return;
			}
			this.PointAlignType = YRevitJigExtend.AlignType.eMiddle;
			if (tmpData.wallTypeId == ElementId.InvalidElementId)
			{
				double num7 = Common.MMToFeet(double.Parse(tmpData.strLeftKeepWarmWidth) + double.Parse(tmpData.strWallWidth) / 2.0);
				this.MutilLineDist.Add(num7);
				this.MutilLineDist.Add(this.nowWidth - num7);
				return;
			}
			double num8 = num + (num2 - num) / 2.0;
			this.MutilLineDist.Add(num8);
			this.MutilLineDist.Add(this.nowWidth - num8);
		}

		private void GetLayerThickness(WallType tmpWallType, ref double dOuterCoreThickness, ref double dInnerCoreThickness, ref double dOuterSurfaceLayerThickness, ref double dInnerSurfaceLayerThickness)
		{
			int num = 0;
			bool flag = false;
			if (tmpWallType.GetCompoundStructure() != null)
			{
				int firstCoreLayerIndex = tmpWallType.GetCompoundStructure().GetFirstCoreLayerIndex();
				int lastCoreLayerIndex = tmpWallType.GetCompoundStructure().GetLastCoreLayerIndex();
				IList<CompoundStructureLayer> layers = tmpWallType.GetCompoundStructure().GetLayers();
				foreach (CompoundStructureLayer compoundStructureLayer in layers)
				{
					dInnerCoreThickness += compoundStructureLayer.Width;
					if (num == lastCoreLayerIndex)
					{
						break;
					}
					if (num < firstCoreLayerIndex)
					{
						dOuterCoreThickness += compoundStructureLayer.Width;
					}
					num++;
				}
				foreach (CompoundStructureLayer compoundStructureLayer2 in layers)
				{
					if ((int)compoundStructureLayer2.Function == 4)
					{
						flag = true;
						break;
					}
					dOuterSurfaceLayerThickness += compoundStructureLayer2.Width;
					if (!flag)
					{
						dOuterSurfaceLayerThickness = 0.0;
					}
				}
				foreach (CompoundStructureLayer compoundStructureLayer3 in layers)
				{
					dInnerSurfaceLayerThickness += compoundStructureLayer3.Width;
					if ((int)compoundStructureLayer3.Function == 5)
					{
						break;
					}
				}
			}
		}

		public XYZ PickStartPointEX(string strPrompt = "请确定直线起点：")
		{
			this.StartPoint = null;
			return this.PickStartPoint(strPrompt);
		}

		public void PickEndPointEX(XYZ ptStart, ref XYZ resEndPt, string strPrompt = "请确定直线终点：", bool ifsingle = false)
		{
			this.PickEndPoint(ptStart, ref resEndPt, strPrompt);
		}

		public YRevitJigExtend(UIDocument uiDoc, DrawWallForm userForm) : base(uiDoc)
		{
			this.JigStage = YRevitJigExtend.EStage.eNoOper;
			this.ResetPoint = XUiJigBase.EResetPoint.eByAxis;
			this.PointAlignType = YRevitJigExtend.AlignType.eMiddle;
			this.MutilLineDist = new List<double>();
			this.DrawEndLine = true;
			int height = Screen.PrimaryScreen.Bounds.Height;
			this.SizeOffset = (int)(0.006 * (double)height);
			this.BorderLength = (int)(0.04 * (double)height);
			this.SizeFont = new Font("Arial", 2.5f * (float)this.SizeOffset, GraphicsUnit.Pixel);
			this.TextFormat = new StringFormat(StringFormatFlags.NoClip);
			this.TextFormat.Alignment = StringAlignment.Center;
			this.TextFormat.LineAlignment = StringAlignment.Center;
			YRevitJigExtend.SizeLineColor = System.Drawing.Color.FromArgb(126, 163, 255);
			YRevitJigExtend.SizeTextBrush = new SolidBrush(base.JigPen.Color);
			this.OnMouseLeaveFormClientEvent = (WndMsgManager.MouseLeaveFormClientEvnetHandler)Delegate.Combine(this.OnMouseLeaveFormClientEvent, new WndMsgManager.MouseLeaveFormClientEvnetHandler(this.OnMouseLeaveFormClientEvnetHandler));
			this.OnMouseMoveIntoFormClientEvent = (WndMsgManager.MouseMoveIntoFormClientEvnetHandler)Delegate.Combine(this.OnMouseMoveIntoFormClientEvent, new WndMsgManager.MouseMoveIntoFormClientEvnetHandler(this.OnMouseMoveIntoFormClientEvnetHandler));
			this.m_UserForm = userForm;
			this.m_useForm = userForm;
		}

		public new void Dispose()
		{
			base.Dispose();
			this.SizeFont.Dispose();
			this.TextFormat.Dispose();
			YRevitJigExtend.SizeTextBrush.Dispose();
			this.OnMouseLeaveFormClientEvent = (WndMsgManager.MouseLeaveFormClientEvnetHandler)Delegate.Remove(this.OnMouseLeaveFormClientEvent, new WndMsgManager.MouseLeaveFormClientEvnetHandler(this.OnMouseLeaveFormClientEvnetHandler));
			this.OnMouseMoveIntoFormClientEvent = (WndMsgManager.MouseMoveIntoFormClientEvnetHandler)Delegate.Remove(this.OnMouseMoveIntoFormClientEvent, new WndMsgManager.MouseMoveIntoFormClientEvnetHandler(this.OnMouseMoveIntoFormClientEvnetHandler));
		}

		private void OnMouseLeaveFormClientEvnetHandler(object sender, EventArgs e)
		{
		}

		private void OnMouseMoveIntoFormClientEvnetHandler(object sender, EventArgs e)
		{
		}

		public XYZ PickStartPoint(string strPrompt = "请确定直线起点：")
		{
			try
			{
				this.JigStage = YRevitJigExtend.EStage.eStartPt;
				this.StartPoint = base.UiDoc.Selection.PickPoint(strPrompt);
			}
			catch
			{
				this.StartPoint = null;
				this.JigStage = YRevitJigExtend.EStage.eNoOper;
				throw;
			}
			this.JigStage = YRevitJigExtend.EStage.eNoOper;
			return this.StartPoint;
		}

		public void PickEndPoint(XYZ ptStart, ref XYZ EndPoint, string strPrompt = "请确定直线终点：")
		{
			try
			{
				this.JigStage = YRevitJigExtend.EStage.eEndPt;
				this.StartPoint = ptStart;
				EndPoint = base.UiDoc.Selection.PickPoint(strPrompt);
				EndPoint = this.GetResetPoint(this.StartPoint, EndPoint);
			}
			catch
			{
				if (this.m_prompDlg != null && base.CmdEndType == XUiJigBase.ECmdEndType.eEnter)
				{
					base.CmdEndType = XUiJigBase.ECmdEndType.eOther;
					XYZ xyz = base.Client2Revit(this.m_ptCur);
					xyz = this.GetResetPoint(this.StartPoint, xyz);
					double num = NumbericTools.mmToFeet(Convert.ToDouble(this.m_prompDlg.GetInputValue()));
					XYZ xyz2 = (new XYZ(xyz.X, xyz.Y, this.StartPoint.Z) - this.StartPoint).Normalize();
					EndPoint = this.StartPoint + xyz2 * num;
					this.m_prompDlg.SetInputValue("");
				}
				else
				{
					EndPoint = null;
				}
				this.JigStage = YRevitJigExtend.EStage.eNoOper;
				throw;
			}
			this.JigStage = YRevitJigExtend.EStage.eNoOper;
		}

		public XYZ GetResetPoint(XYZ ptBase, XYZ ptUser)
		{
			XYZ result = ptUser;
			if (this.ResetPoint == XUiJigBase.EResetPoint.eByAngle)
			{
				result = JigFuncs.GetProjectPoint(base.UiDoc, ptUser, ptBase, this.LineAngle);
			}
			else if (this.ResetPoint == XUiJigBase.EResetPoint.eByOrtho)
			{
				result = JigFuncs.GetOrthoPoint(base.UiDoc, ptUser, ptBase);
			}
			else if (this.ResetPoint == XUiJigBase.EResetPoint.eByAxis)
			{
				XYZ axisPoint = JigFuncs.GetAxisPoint(base.UiDoc, ptUser, ptBase);
				if (axisPoint != null)
				{
					result = axisPoint;
				}
			}
			return result;
		}

		public override void Draw(PaintEventArgs paintEventArgs)
		{
			base.Draw(paintEventArgs);
			if (this.m_ptCur.IsEmpty || this.JigStage != YRevitJigExtend.EStage.eEndPt)
			{
				return;
			}
			XYZ xyz = base.Client2Revit(this.m_ptCur);
			if (this.ResetPoint == XUiJigBase.EResetPoint.eByAngle)
			{
				xyz = JigFuncs.GetProjectPoint(base.UiDoc, xyz, this.StartPoint, this.LineAngle);
				this.m_ptCur = base.Revit2Client(xyz);
			}
			else if (this.ResetPoint == XUiJigBase.EResetPoint.eByOrtho)
			{
				xyz = JigFuncs.GetOrthoPoint(base.UiDoc, xyz, this.StartPoint);
				this.m_ptCur = base.Revit2Client(xyz);
			}
			else if (this.ResetPoint == XUiJigBase.EResetPoint.eByAxis)
			{
				XYZ axisPoint = JigFuncs.GetAxisPoint(base.UiDoc, xyz, this.StartPoint);
				if (axisPoint != null)
				{
					xyz = axisPoint;
					this.m_ptCur = base.Revit2Client(xyz);
					base.DrawAxisLine(paintEventArgs.Graphics, this.StartPoint, xyz);
				}
			}
			XGraphics xgraphics = new XGraphics(paintEventArgs.Graphics, base.JigPen);
			double feet = this.StartPoint.DistanceTo(xyz);
			string.Format("{0:F1}", NumbericTools.feetTomm(feet));
			if (this.MutilLineDist.Count < 1)
			{
				new XLine2D(base.Revit2Client(this.StartPoint), this.m_ptCur).Draw(xgraphics);
				this.DrawLineSize(this.StartPoint, xyz, xgraphics);
				return;
			}
			this.DrawMutilLine(this.StartPoint, xyz, xgraphics);
			this.DrawLineSize(this.StartPoint, xyz, xgraphics);
		}

		public double LineAngle { get; set; }

		public XYZ StartPoint { get; set; }

		public XYZ EndPoint { get; set; }

		public YRevitJigExtend.EStage JigStage { get; set; }

		public XUiJigBase.EResetPoint ResetPoint { get; set; }

		public YRevitJigExtend.AlignType PointAlignType { get; set; }

		public List<double> MutilLineDist { get; set; }

		public void DrawMutilLine(XYZ ptBaseS, XYZ ptBaseE, XGraphics graphics)
		{
			Transform transform = Transform.CreateRotation(base.UiDoc.ActiveView.ViewDirection, -Math.PI*.5);
			XYZ xyz = (ptBaseE - ptBaseS).Normalize();
			XYZ xyz2 = transform.OfVector(xyz);
			double num = 0.0;
			foreach (double num2 in this.MutilLineDist)
			{
				num += num2;
			}
			double num3 = 0.0;
			if (this.PointAlignType == YRevitJigExtend.AlignType.eRight)
			{
				num3 = num;
			}
			else if (this.PointAlignType == YRevitJigExtend.AlignType.eMiddle)
			{
				num3 = this.MutilLineDist[0];
			}
			ptBaseS -= xyz2 * num3;
			ptBaseE -= xyz2 * num3;
			if (this.DrawEndLine)
			{
				XYZ point = ptBaseS + xyz2 * num;
				XYZ point2 = ptBaseE + xyz2 * num;
				XLine2D xline2D = new XLine2D(base.Revit2Client(ptBaseS), base.Revit2Client(point));
				XDrawable2D xdrawable2D = new XLine2D(base.Revit2Client(ptBaseE), base.Revit2Client(point2));
				xline2D.Draw(graphics);
				xdrawable2D.Draw(graphics);
			}
			new XLine2D(base.Revit2Client(ptBaseS), base.Revit2Client(ptBaseE)).Draw(graphics);
			foreach (double num4 in this.MutilLineDist)
			{
				ptBaseS += xyz2 * num4;
				ptBaseE += xyz2 * num4;
				new XLine2D(base.Revit2Client(ptBaseS), base.Revit2Client(ptBaseE)).Draw(graphics);
			}
		}

		public bool DrawEndLine { get; set; }

		public int SizeOffset { get; set; }

		public int BorderLength { get; set; }

		public Font SizeFont { get; set; }

		public StringFormat TextFormat { get; set; }

		public static System.Drawing.Color SizeLineColor { get; set; }

		public static SolidBrush SizeTextBrush { get; set; }

		public void DrawLineSize(XYZ ptFrom, XYZ ptTo, XGraphics graphics)
		{
			System.Drawing.Point point = base.Revit2Client(ptFrom);
			System.Drawing.Point point2 = base.Revit2Client(ptTo);
			XUiJigBase.SortTwoPoint(ref point, ref point2);
			if (XUiJigBase.TwoPointDist(point, point2) < 10)
			{
				return;
			}
			double num = XUiJigBase.TwoPointAngle(point, point2);
			double dAngle = num + Math.PI*.5;
			System.Drawing.Color color = graphics.m_pen.Color;
			graphics.m_pen.Color = YRevitJigExtend.SizeLineColor;
			System.Drawing.Point point3 = XUiJigBase.OffsetPoint(point, dAngle, this.SizeOffset);
			System.Drawing.Point point4 = XUiJigBase.OffsetPoint(point2, dAngle, this.SizeOffset);
			System.Drawing.Point ptEnd = XUiJigBase.OffsetPoint(point3, dAngle, this.BorderLength);
			new XLine2D(point3, ptEnd).Draw(graphics);
			System.Drawing.Point ptEnd2 = XUiJigBase.OffsetPoint(point4, dAngle, this.BorderLength);
			new XLine2D(point4, ptEnd2).Draw(graphics);
			System.Drawing.Point ptFrom2 = XUiJigBase.OffsetPoint(point3, dAngle, this.BorderLength - this.SizeOffset);
			point4 = XUiJigBase.OffsetPoint(point4, dAngle, this.BorderLength - this.SizeOffset);
			new XLine2D(XUiJigBase.OffsetPoint(ptFrom2, num, -this.SizeOffset), XUiJigBase.OffsetPoint(point4, num, this.SizeOffset)).Draw(graphics);
			double feet = ptFrom.DistanceTo(ptTo);
			System.Drawing.Point point5 = XUiJigBase.OffsetPoint(XUiJigBase.OffsetPoint(ptFrom2, num, XUiJigBase.TwoPointDist(point, point2) / 2), dAngle, (int)((double)this.SizeOffset + (double)this.SizeFont.Height / 2.0));
			PointF point6 = new PointF((float)point5.X, (float)point5.Y);
			float angle = -(float)(num / Math.PI * 180.0);
			graphics.m_graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
			Matrix transform = graphics.m_graphics.Transform;
			Matrix transform2 = graphics.m_graphics.Transform;
			transform2.RotateAt(angle, point6);
			string s = string.Format("{0:F1}", NumbericTools.feetTomm(feet));
			graphics.m_graphics.Transform = transform2;
			graphics.m_graphics.DrawString(s, this.SizeFont, YRevitJigExtend.SizeTextBrush, point6, this.TextFormat);
			graphics.m_graphics.Transform = transform;
			graphics.m_pen.Color = color;
		}

		private double nowWidth = 2.0;

		private DrawWallForm m_useForm;

		public enum EStage
		{
			eNoOper,
			eStartPt,
			eEndPt
		}

		public enum AlignType
		{
			eRight,
			eMiddle,
			eLeft
		}
	}
}
